import os
import shutil
import time
import argparse
from argparse import Namespace
import numpy as np
import numpy
import torch
import torch.backends.cudnn as cudnn
from numpy import random

import dlib
# import camera as camera
import cv2
from dateutil.relativedelta import relativedelta
from django.contrib import auth
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.db.models.functions import datetime
from django.http import HttpResponse, StreamingHttpResponse
from django.shortcuts import render, redirect

# Create your views here.
from django.urls import reverse
from django.utils import timezone
import datetime

from django.views.decorators.csrf import csrf_exempt

from IntrusionDetectionSystem.settings import MEDIA_ROOT, MEDIA_URL
from gui_buttons import Buttons
from intrusionDect.getFace import getFace
from intrusionDect.getFeature import reFlushFaceDB
from intrusionDect.models import trustedStaff, alarmRecord, trustedStaffPermission, region, videos
import gol
import pandas as pd
import threading
# import winsound
from mail import email
import gol
import random
from sendSms import send_code, send_prompt
from detect_webcam import detect
from detect_webcam import Config
from django.contrib import messages
from django.http import JsonResponse

from models.experimental import attempt_load
from utils.datasets import LoadStreams, LoadImages, letterbox
from utils.general import check_img_size, check_requirements, check_imshow, non_max_suppression, apply_classifier, \
    scale_coords, xyxy2xywh, strip_optimizer, set_logging, increment_path
from utils.plots import plot_one_box
from utils.torch_utils import select_device, load_classifier, time_synchronized
import tkinter.messagebox #弹窗库
from tkinter import *

@csrf_exempt
def getcode(request):
    email = request.POST.get('email')
    code = request.POST.get('code')
    send_code(email, code)
    request.session['code'] = code
    response = {'send_code': 'success'}
    return JsonResponse(response)

# 注销当前用户并重定向到登录页面。
def log_out(request):
    logout(request)
    return redirect(reverse("login"))


def mylogin(request):
    if request.method == 'GET':
        return render(request, 'login.html')
    if request.method == 'POST':
        name = request.POST.get('userName')
        password = request.POST.get('password')
        print(name, password)
        user = authenticate(username=name, password=password)   # 调用authenticate函数进行身份认证
        print(user)
        if user:
            login(request, user)
            request.session['userName'] = name
            return redirect(reverse('gly-rt-monitor'))
            # return HttpResponse("登陆成功！")
        return redirect(reverse('login'))
        #return HttpResponse(f"{name} ,{password} 登陆失败！")


# 注册函数
def register(request):
    if request.method == 'POST':
        userName = request.POST['userName']
        email = request.POST['email']
        password = request.POST['password']
        code = request.POST['code']

        if request.session.get('code') != code:
            messages.error(request, "验证码错误")
            return redirect(reverse("login"))  # 跳转到登录页面
        user = authenticate(username=userName, password=password)  # 判断用户是否存在
        if user:
            return HttpResponse('用户已存在')
        User.objects.create_user(username=userName, email=email, password=password)  # 创建用户保存在auth_user表中
    return redirect(reverse("login"))  # 跳转到登录页面



gol.set_value('xpos2', 0)
gol.set_value('ypos2', 0)
gol.set_value('width2', 1)
gol.set_value('height2', 1)

gol.set_value('xpos3', 0)
gol.set_value('ypos3', 0)
gol.set_value('width3', 1)
gol.set_value('height3', 1)

gol.set_value('xpos4', 0)
gol.set_value('ypos4', 0)
gol.set_value('width4', 1)
gol.set_value('height4', 1)

gol.set_value('alarm1', 0)
gol.set_value('alarm2', 0)
gol.set_value('alarm3', 0)
gol.set_value('alarm4', 0)

gol.set_value('otherObject', 'dog')

# def listenAlarm():
#     # while True:
#         if gol.get_value('alarm1')==1:
#             email('zpc6767@163.com','摄像头1出现报警')
#             gol.set_value('alarm1', 0)
#         if gol.get_value('alarm2')==1:
#             email('zpc6767@163.com','摄像头2出现报警')
#             gol.set_value('alarm2', 0)
#         if gol.get_value('alarm3')==1:
#             email('zpc6767@163.com','摄像头3出现报警')
#             gol.set_value('alarm3', 0)
#         if gol.get_value('alarm4')==1:
#             email('zpc6767@163.com','摄像头4出现报警')
#             gol.set_value('alarm4', 0)

# listenThread=threading.Thread(target = listenAlarm)
# listenThread.start()

def alarmSound():
    duration = 1000  # millisecond
    freq = 440  # Hz
    #winsound.Beep(freq, duration)

print('---------------------------')

# 这是人脸识别功能！对应video2！目前对应刘家璇手机摄像头
def faceDetection(addr, cno):
    now_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
    face_video = False
    face_count = 0

    allFace = 0
    knownFace = 0

    fourcc = cv2.VideoWriter_fourcc('H', '2', '6', '4')  # 定义视频解码器
    # 人脸识别模型，提取128D的特征矢量
    facerec = dlib.face_recognition_model_v1(
        "/Users/yangyafei/Desktop/face/dlibfile/dlib_face_recognition_resnet_model_v1.dat")

    # 计算两个128D向量间的欧式距离
    def return_euclidean_distance(feature_1, feature_2):
        feature_1 = np.array(feature_1)
        feature_2 = np.array(feature_2)
        dist = np.sqrt(np.sum(np.square(feature_1 - feature_2)))
        return dist

    # 处理存放所有人脸特征的 csv
    path_features_known_csv = "/Users/yangyafei/Desktop/features_all.csv"
    csv_rd = pd.read_csv(path_features_known_csv, header=None)

    # 用来存放所有录入人脸特征的数组
    features_known_arr = []

    # 读取已知人脸数据
    # print known faces
    for i in range(csv_rd.shape[0]):
        features_someone_arr = []
        for j in range(0, len(csv_rd.iloc[i, :])):
            features_someone_arr.append(csv_rd.iloc[i, :][j])
        features_known_arr.append(features_someone_arr)
    print("Faces in Database：", len(features_known_arr))

    # Dlib 检测器和预测器
    detector = dlib.get_frontal_face_detector()
    predictor = dlib.shape_predictor(
        "/Users/yangyafei/Desktop/face/dlibfile/shape_predictor_68_face_landmarks.dat")

    # 按钮初始化
    button = Buttons()
    button.set_object('person')
    button.set_object('cat')
    colors = button.colors

    # Opencv DNN,传入模型结构和参数文件
    net = cv2.dnn.readNet("dnn_model/yolov4-tiny.weights", "dnn_model/yolov4-tiny.cfg")
    #定义一个目标检测模型，把模型传进去
    model = cv2.dnn_DetectionModel(net)
    #设置模型的输入
    model.setInputParams(size=(320, 320), scale=1 / 255)

    # Load class lists
    classes = []  # 存放每个分类的名称
    with open("dnn_model/classes.txt", "r") as file_object:
        for class_name in file_object.readlines():
            class_name = class_name.strip()
            classes.append(class_name)

    print("Objects list")
    print(classes)

    # 创建 cv2 摄像头对象，这里使用本机摄像头
    # 人脸识别功能模块对应video1，对应gen_display方法，对应本机摄像头！！
    cap = cv2.VideoCapture(addr)

    """
    视频流生成器
    """
    count = 0
    emailCount = 1800  # 初始邮件计数1800
    firstRet, firstFrame = cap.read()

    # 若读取到摄像头，即firstRet为真，就保存一张视频图像
    if firstRet:
        cv2.imwrite('/Users/yangyafei/Desktop/face/media/cameraArea/' + 'camera' + str(cno) + '.jpg',
                    firstFrame)
    while True:
        count += 1
        emailCount += 1

        # 划定初始的监控范围，此范围以外不被检测，此范围以内会被检测
        gol.set_value('xpos1', 0.5)
        gol.set_value('ypos1', 0)
        gol.set_value('width1', 0.5)
        gol.set_value('height1', 1)

        flag, original_img = cap.read()

        if flag:
            size = original_img.shape
            w = size[1]
            h = size[0]

            gx = 0
            gy = 0
            gw = w
            gh = h
            if cno == 1:
                gx = gol.get_value('xpos1') * w
                gy = gol.get_value('ypos1') * h
                gw = gol.get_value('width1') * w
                gh = gol.get_value('height1') * h

            gx = int(gx)
            gy = int(gy)
            gw = int(gw)
            gh = int(gh)

            #对读取到的图像进行裁剪和绘制矩形框的操作
            img_rd = original_img[gy:(gy + gh), gx:(gx + gw)]
            cv2.rectangle(original_img, (gx, gy), (gx + gw, gy + gh), (0, 255, 255), 5)

            ret, frame = flag, img_rd
            # Get active buttons list
            active_buttons = ['person']
            active_buttons.append(gol.get_value('otherObject'))
            # print("Active buttons", active_buttons)

            # Object Detection
            (class_ids, scores, bboxes) = model.detect(frame, confThreshold=0.3, nmsThreshold=.4)
            for class_id, score, bbox in zip(class_ids, scores, bboxes):
                (x, y, w, h) = bbox
                class_name = classes[class_id]
                color = colors[class_id]

                if class_name in active_buttons:
                    face_video = True
                    cv2.putText(img_rd, class_name, (x, y - 10), cv2.FONT_HERSHEY_PLAIN, 2, color, 2)
                    cv2.rectangle(img_rd, (x, y), (x + w, y + h), color, 5)

            # Display buttons
            button.display_buttons(img_rd)

            ################################################################################
            ################################################################################
            # 取灰度
            img_gray = cv2.cvtColor(img_rd, cv2.COLOR_RGB2GRAY)

            # 人脸数 faces
            faces = detector(img_gray, 0)

            # 待会要写的字体 font to write later
            font = cv2.FONT_HERSHEY_COMPLEX

            # 存储当前摄像头中捕获到的所有人脸的坐标/名字
            # the list to save the positions and names of current faces captured
            pos_namelist = []
            name_namelist = []

            # 检测到人脸 when face detected
            if len(faces) != 0:
                allFace += 1

                # 获取当前捕获到的图像的所有人脸的特征，存储到 features_cap_arr
                # get the features captured and save into features_cap_arr
                features_cap_arr = []
                for i in range(len(faces)):
                    shape = predictor(img_rd, faces[i])
                    features_cap_arr.append(facerec.compute_face_descriptor(img_rd, shape))

                # 遍历捕获到的图像中所有的人脸
                # traversal all the faces in the database
                for k in range(len(faces)):
                    # print("##### camera person", k + 1, "#####")
                    # 让人名跟随在矩形框的下方
                    # 确定人名的位置坐标
                    # 先默认所有人不认识，是 unknown
                    name_namelist.append("unknown")

                    # 每个捕获人脸的名字坐标 the positions of faces captured
                    pos_namelist.append(
                        tuple([faces[k].left(), int(faces[k].bottom() + (faces[k].bottom() - faces[k].top()) / 4)]))

                    # 对于某张人脸，遍历所有存储的人脸特征
                    # for every faces detected, compare the faces in the database
                    e_distance_list = []
                    for i in range(len(features_known_arr)):
                        # 如果 person_X 数据不为空
                        if str(features_known_arr[i][0]) != '0.0':
                            # print("with person", str(i + 1), "the e disqtance: ", end='')
                            e_distance_tmp = return_euclidean_distance(features_cap_arr[k], features_known_arr[i])
                            # print(e_distance_tmp)
                            e_distance_list.append(e_distance_tmp)
                        else:
                            # 空数据 person_X
                            e_distance_list.append(999999999)
                    # 找出最接近的一个人脸数据是第几个
                    # Find the one with minimum e distance
                    similar_person_num = e_distance_list.index(min(e_distance_list))
                    # print("Minimum e distance with person", int(similar_person_num) + 1)

                    # 计算人脸识别特征与数据集特征的欧氏距离
                    # 距离小于0.5则标出为可识别人物
                    if min(e_distance_list) < 0.45:
                        knownFace += 1
                        # 这里可以修改摄像头中标出的人名
                        # Here you can modify the names shown on the camera
                        # 1、遍历文件夹目录
                        folder_name = 'C:/Users/86136/Desktop/faces'
                        # 最接近的人脸
                        sum = similar_person_num + 1
                        key_id = 1  # 从第一个人脸数据文件夹进行对比
                        # 获取文件夹文件名
                        file_names = os.listdir(folder_name)
                        for name in file_names:
                            # print(name+'->'+str(key_id))
                            if sum == key_id:
                                # winsound.Beep(300,500)# 响铃：300频率，500持续时间
                                name_namelist[k] = name[0:]  # 人名删去第一个数字（用于视频输出标识）
                            key_id += 1
                        # -----------筛选出人脸并保存到visitor文件夹------------
                        print("============================================", (knownFace * 1.0) / allFace)
                        if (allFace >= 40 and (knownFace * 1.0) / allFace >= 0.5):
                            allFace = 0
                            knownFace = 0
                            for i, d in enumerate(faces):
                                x1 = d.top() if d.top() > 0 else 0
                                y1 = d.bottom() if d.bottom() > 0 else 0
                                x2 = d.left() if d.left() > 0 else 0
                                y2 = d.right() if d.right() > 0 else 0
                                face = img_rd[x1:y1, x2:y2]
                                size = 64
                                face = cv2.resize(face, (size, size))
                                # 要存储visitor人脸图像文件的路径
                                path_visitors_save_dir = '/Users/yangyafei/Desktop/face/media/visitor/isknown'
                                # 存储格式：2019-06-24-14-33-40LQH.jpg
                                now_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
                                picName = str(now_time) + str(name_namelist[k])
                                save_name = str(now_time) + str(name_namelist[k]) + '.jpg'
                                # print(save_name)
                                # 本次图片保存的完整url
                                save_path = path_visitors_save_dir + '/' + save_name
                                # 遍历visitor文件夹所有文件名
                                visitor_names = os.listdir(path_visitors_save_dir)
                                visitor_name = ''

                                manName = str(name_namelist[k])
                                # for name in visitor_names:
                                #     # 名字切片到分钟数：2019-06-26-11-33-00LQH.jpg
                                now = datetime.datetime.now()
                                regionNum = region.objects.filter(cameraId=getCameraId(cno)).first()
                                records = trustedStaffPermission.objects.filter(regionId=regionNum, name=manName,
                                                                                start_time__lte=now,
                                                                                end_time__gte=now)
                                print("################################################", records.count())
                                if not records:
                                    if emailCount >= 2000:
                                        # thd = threading.Thread(target=email,
                                        #                         args=(
                                        #                         "21301072@bjtu.edu.cn", '加油机旁出现不可信人员'))
                                        # thd.start()
                                        email('21301072@bjtu.edu.cn','加油机旁出现不可信人员')

                                        emailCount = 0

                                    cv2.imwrite(save_path, face)
                                    tsound = threading.Thread(target=alarmSound)
                                    tsound.start()

                                    alarmRec = alarmRecord(cameraId=getCameraId(cno), region=getRegionId(cno),
                                                           intrusionTime=datetime.datetime.now(),
                                                           photo=picName, alarmLevel=0)
                                    alarmRec.save()




                    elif allFace >= 40 and (knownFace * 1.0) / allFace < 0.2:
                        allFace = 0
                        knownFace = 0
                        # -----------筛选出人脸并保存到visitor文件夹------------
                        for i, d in enumerate(faces):
                            x1 = d.top() if d.top() > 0 else 0
                            y1 = d.bottom() if d.bottom() > 0 else 0
                            x2 = d.left() if d.left() > 0 else 0
                            y2 = d.right() if d.right() > 0 else 0
                            face = img_rd[x1:y1, x2:y2]
                            size = 64
                            face = cv2.resize(face, (size, size))
                            # 要存储visitor-》unknown人脸图像文件的路径
                            path_visitors_save_dir = "/Users/yangyafei/Desktop/face/media/visitor/unknown"
                            # 存储格式：2019-06-24-14-33-40unknown.jpg
                            now_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
                            # print(save_name)
                            # 本次图片保存的完整url
                            save_path = path_visitors_save_dir + '/' + str(now_time) + 'unknown.jpg'
                            # 播放声音
                            ##########
                            tsound = threading.Thread(target=alarmSound)
                            tsound.start()
                            ############
                            cv2.imwrite(save_path, face)
                            upicname = str(now_time) + 'unknown'
                            alarmRec = alarmRecord(cameraId=getCameraId(cno), region=getRegionId(cno),
                                                   intrusionTime=datetime.datetime.now(),
                                                   photo=upicname, alarmLevel=1)
                            alarmRec.save()
                            if emailCount >= 2000:
                                # thd = threading.Thread(target=email,
                                #                        args=("21301072@bjtu.edu.cn", '摄像头1出现不可信人员入侵'))
                                # thd.start()
                                email('21301072@bjtu.edu.cn', '加油机旁出现不可信人员')
                                emailCount = 0
                            # print('新存储：' + path_visitors_save_dir + '/' + str(now_time) + 'unknown.jpg')

                    # 矩形框
                    for kk, d in enumerate(faces):
                        # 绘制矩形框
                        cv2.rectangle(img_rd, tuple([d.left(), d.top()]), tuple([d.right(), d.bottom()]), (0, 255, 255),
                                      2)

                # 在人脸框下面写人脸名字
                for i in range(len(faces)):
                    cv2.putText(img_rd, name_namelist[i], pos_namelist[i], font, 0.8, (0, 255, 255), 1, cv2.LINE_AA)
            key = cv2.waitKey(1)
            if key == 27:
                break

            #############################################################################################################################
            if (face_video == True):
                if (face_count == 0):
                    path = '/Users/yangyafei/Desktop/face/media/videos/' + str(now_time) + '.mp4'
                    face_video_out = cv2.VideoWriter(path, fourcc, 10, (1000, 600))
                    ###############################################################################
                    # 写入数据库
                    ###############################################################################
                    video = videos(startTime=now_time, videoName=now_time + '.mp4')
                    video.save()
                if (face_count == 800):
                    face_video = False
                    face_count = 0
                else:
                    img = img_rd
                    img = cv2.resize(img, (1000, 600))  # 一定要记得对获取帧进行尺寸变换，等于定义的写入帧的尺寸
                    face_video_out.write(img)
                    face_count += 1
            else:
                face_count = 0

            # 读取图片
            ret = flag
            frame = original_img
            if ret:
                frame = cv2.resize(frame, (0, 0), fx=0.5, fy=0.5)
                # 将图片进行解码
                ret, jpeg = cv2.imencode('.jpg', frame)  # 将帧编码为JPEG格式
                yield (b'--frame\r\n'
                       b'Content-Type: image/jpeg\r\n\r\n' + jpeg.tobytes() + b'\r\n\r\n')  # 以multi-part格式生成帧数据


# 四个摄像头
def getCameraId(idNum):
    if idNum == 1:
        return '摄像头1'
    if idNum == 2:
         return '摄像头2'
    if idNum == 3:
        return '摄像头3'
    if idNum == 4:
        return '摄像头4'

#四个摄像头地点
def getRegionId(idNum):
    if idNum == 1:
        return '加油站入口'
    if idNum == 2:
        return '加油站出口'
    if idNum == 3:
        return '加油机'
    if idNum == 4:
        return '危险区域'

def carCheck(classids, bboxes):
   count = gol.get_value('count')
   if count == 0:
       for class_id, bbox in zip(classids, bboxes):
           if class_id == 2:
               print("记录一下")
               startTime = time.perf_counter()
               gol.set_value('carLocation', bbox)
               gol.set_value('startTime', startTime)
               gol.set_value('count', 2)

   if count == 1:
       for class_id, bbox in zip(classids, bboxes):
           if class_id == 2:
               x, y, w, h = bbox
               location = gol.get_value('carLocation')
               x1, y1, w1, h1 = location
               if abs(x - x1) < 200 and abs(y - y1) < 200:
                   print('车来了')
                   send_prompt("861403302@qq.com")
                   gol.set_value('count', 0)

   if count == 2:
       endTime = time.perf_counter()
       if (endTime - gol.get_value('startTime')) > 10:
           print("大于10秒了")
           gol.set_value('count', 1)
       else:
            print("时间差点")

#  这个是车辆检测功能，对应video和video1！！目前对应本机摄像头和刘培钰手机摄像头
def carDetection(addr, cno):
   gol.set_value('count', 0)

   # （1）导入yolov4-tiny网络模型结构
   # 传入模型结构.cfg文件，模型权重参数.weight文件
   net = cv2.dnn.readNet('dnn_model/yolov4-tiny.cfg', 'dnn_model/yolov4-tiny.weights')

   # 定义一个目标检测模型，将模型传进去
   model = cv2.dnn_DetectionModel(net)

   # 设置模型的输入
   model.setInputParams(size=(320, 320), scale=1 / 255)

   # （2）获取分类文本的信息
   classes = []  # 存放每个分类的名称
   with open('dnn_model/classes.txt') as file_obj:
       # 获取文本中的每一行
       for class_name in file_obj.readlines():
           # 删除文本中的换行符、空格等
           class_name = class_name.strip()
           # 将每个分类名保存到列表中
           classes.append(class_name)

   cap = cv2.VideoCapture(addr)  # 打开摄像头
   while True:
       # 返回是否读取成功ret和读取的帧图像frame
       ret, frame = cap.read()

       # 图像比较大把它缩小一点
       frame = cv2.resize(frame, (1280, 720))

       # 视频比较短，循环播放
       if cap.get(cv2.CAP_PROP_POS_FRAMES) == cap.get(cv2.CAP_PROP_FRAME_COUNT):
           # 如果当前帧==总帧数，那就重置当前帧为0
           cap.set(cv2.CAP_PROP_POS_FRAMES, 0)

       # 目标检测
       classids, scores, bboxes = model.detect(frame, 0.5, 0.3)

       print('classids:', classids)  # 如：[0]
       print('score:', scores)  # 如：0.9469002
       print('bboxes:', bboxes)  # 如：[159 176 816 533]

       if 2 in classids:
           print("lalalalalalalalalalalalalalalal")
           carCheck(classids, bboxes)

       # （5）显示检测结果
       # 遍历所有的检测框信息，把它们绘制出来
       for class_id, score, bbox in zip(classids, scores, bboxes):
           # 获取检测框的左上角坐标和宽高
           x, y, w, h = bbox

           # 获取检测框对应的分类名
           class_name = classes[class_id]

           # 绘制矩形框
           cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2)
           # 显示分类文本
           cv2.putText(frame, class_name, (x, y + h + 20), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 0), 2)
           # 显示类别概率
           cv2.putText(frame, str(int(score * 100)) + '%', (x, y - 5), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 255),2)

       # （6）显示图像
       ret, jpeg = cv2.imencode('.jpg', frame)  # 将帧编码为JPEG格式
       yield (b'--frame\r\n'
              b'Content-Type: image/jpeg\r\n\r\n' + jpeg.tobytes() + b'\r\n\r\n')  # 以multi-part格式生成帧数据

# 这个是吸烟检测功能！！对应video3！！目前对应杨亚菲摄像头
def smokingDetection(addr, cno):
    # 加载模型权重
    imgsz=640
    weights = 'weights/last.pt'
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    half = device.type != 'cpu'  # half precision only supported on CUDA
    from models.experimental import attempt_load
    model = attempt_load(weights, map_location=device)
    model.eval()
    stride = int(model.stride.max())  # model stride
    imgsz = check_img_size(imgsz, s=stride)  # check img_size
    if half:
        model.half()  # to FP16

    # 设置置信度阈值
    conf_threshold = 0.65

    cap = cv2.VideoCapture(addr)  # 打开摄像头
    while True:
        ret, frame = cap.read()
        frame_disp = frame.copy()

        # 图像预处理
        from yolov5.utils.datasets import letterbox
        img = letterbox(frame_disp, 640, stride=stride)[0]
        img = img[:, :, ::-1].transpose(2, 0, 1)  # BGR to RGB, to 3x416x416
        import numpy
        img = numpy.ascontiguousarray(img)
        img = torch.from_numpy(img).to(device)
        img = img.half() if half else img.float()  # uint8 to fp16/32
        img /= 255.0  # 0 - 255 to 0.0 - 1.0
        if img.ndimension() == 3:
            img = img.unsqueeze(0)
        # 目标检测
        pred = model(img)[0]
        pred = non_max_suppression(pred, conf_threshold, 0.45)

        for det in pred:
            if len(det):
                det[:, :4] = scale_coords(img.shape[2:], det[:, :4], frame.shape).round()

                for *xyxy, conf, cls in reversed(det):
                    x1, y1, x2, y2 = map(int, xyxy)
                    label = f'Action: Smoking {conf:.2f}'
                    cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 255, 0), 2)
                    cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

        ret, jpeg = cv2.imencode('.jpg', frame)
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + jpeg.tobytes() + b'\r\n\r\n')





def video(request):
    """
    视频流路由。将其放入img标记的src属性中。
    例如：<img src='https://ip:port/uri' >
    """
    return StreamingHttpResponse(carDetection(0,1), content_type='multipart/x-mixed-replace; boundary=frame')


def video1(request):
    return StreamingHttpResponse(carDetection("http://121.36.57.101:8080/lpy/123.flv",2),
                                 content_type='multipart/x-mixed-replace; boundary=frame')

#
def video2(request):
    return StreamingHttpResponse(faceDetection('http://121.36.57.101:8080/liu/123.flv',3),
                                 content_type='multipart/x-mixed-replace; boundary=frame')


def video3(request):
    return StreamingHttpResponse(smokingDetection('http://121.36.57.101:8080/yang/123.flv',4),
                                 content_type='multipart/x-mixed-replace; boundary=frame')


def prepareRTMonitorPage():
    # rec.intrusionTime    rec.cameraId   rec.region   rec.alarmLevel
    records = []
    images = []
    num = 0
    recs = alarmRecord.objects.filter(intrusionTime__gte=timezone.now().date())
    for rec in recs:
        num += 1
        records.append(rec)

        if rec.alarmLevel == 0:
            images.append('C:/Users/86136/Desktop/media/visitor/isknown/' + rec.photo + '.jpg')
        if rec.alarmLevel == 1:
            images.append('C:/Users/86136/Desktop/media/visitor/unknown/' + rec.photo + '.jpg')

    data = {'records': records, 'num': num, 'images': images}
    return data


def prepareRecordPage():
    records = []
    images = []
    num = 0
    recs = alarmRecord.objects.all()
    for rec in recs:
        num = num + 1
        records.append(rec)
        if rec.alarmLevel == 0:
            images.append('C:/Users/86136/Desktop/media/visitor/isknown/' + rec.photo + '.jpg')
        if rec.alarmLevel == 1:
            images.append('C:/Users/86136/Desktop/media/visitor/unknown/' + rec.photo + '.jpg')
    data = {'records': records, 'num': num, 'images': images}
    return data


def prepareInfoManagerPage():
    recs = trustedStaff.objects.all()
    recos = User.objects.all()
    recors = trustedStaffPermission.objects.all()

    records1 = []
    images1 = []
    num1 = 0
    for rec in recs:
        num1 = num1 + 1
        records1.append(rec)
        images1.append(os.path.join(MEDIA_URL, str(rec.image)))

    records2 = []
    num2 = 0
    for rec in recos:
        num2 = num2 + 1
        records2.append(rec)

    records3 = []
    num3 = 0
    for rec in recors:
        num3 = num3 + 1
        records3.append(rec)

    rgns = []
    for reg in region.objects.all():
        rgns.append(reg)

    # 构造统计图数据
    truPers = trustedStaffPermission.objects.all()
    trustaffs1 = set()
    trustaffs2 = set()
    trustaffs3 = set()
    trustaffs4 = set()
    for truPer in truPers:
        if truPer.regionId.cameraId == '摄像头1':
            trustaffs1.add(truPer.name.name)
        elif truPer.regionId.cameraId == '摄像头2':
            trustaffs2.add(truPer.name.name)
        elif truPer.regionId.cameraId == '摄像头3':
            trustaffs3.add(truPer.name.name)
        elif truPer.regionId.cameraId == '摄像头4':
            trustaffs4.add(truPer.name.name)
    nums = []
    nums.append(len(trustaffs1))
    nums.append(len(trustaffs2))
    nums.append(len(trustaffs3))
    nums.append(len(trustaffs4))

    data = {'records1': records1, 'num1': num1, 'images1': images1, 'num2': num2, 'records2': records2, 'num3': num3,
            'records3': records3, 'rgns': rgns, 'nums': nums}

    return data


def prepareStatisticPage():
    # 拿到每个摄像头当天的数据
    datalists = [[], [], [], []]
    monthLists = [[], [], [], []]
    month_day = []
    for i in range(4):
        cameraName = '摄像头' + str(i + 1)
        # 获取当天数据
        for j in range(24):
            # now = datetime.datetime.now()
            # zero_today = now - datetime.timedelta(hours=now.hour, minutes=now.minute, seconds=now.second,
            #                                       microseconds=now.microsecond)
            # last_today = zero_today + datetime.timedelta(hours=23, minutes=59, seconds=59)
            now = datetime.datetime.now()
            start = datetime.datetime(year=now.year, month=now.month, day=now.day, hour=j, minute=0, second=0)

            end = datetime.datetime(year=now.year, month=now.month, day=now.day, hour=j, minute=59, second=59)

            num = alarmRecord.objects.filter(cameraId=cameraName, intrusionTime__gte=start,
                                             intrusionTime__lte=end).count()
            datalists[i].append(num)

        # 获取该月第一天到今天目前的数据
        now = datetime.datetime.now()
        month_day = list(range(1, now.day + 1))
        for k in range(1, now.day + 1):
            start = datetime.datetime(year=now.year, month=now.month, day=k, hour=0, minute=0, second=0)
            end = datetime.datetime(year=now.year, month=now.month, day=k, hour=23, minute=59, second=59)
            num = alarmRecord.objects.filter(cameraId=cameraName, intrusionTime__gte=start,
                                             intrusionTime__lte=end).count()
            monthLists[i].append(num)

    dataList1 = datalists[0]
    dataList2 = datalists[1]
    dataList3 = datalists[2]
    dataList4 = datalists[3]

    monthDatalist5 = monthLists[0]
    monthDatalist6 = monthLists[1]
    monthDatalist7 = monthLists[2]
    monthDatalist8 = monthLists[3]



    data = {'dataList1': dataList1, 'dataList2': dataList2, 'dataList3': dataList3, 'dataList4': dataList4,
            'dataList5': monthDatalist5, 'dataList6': monthDatalist6, 'dataList7': monthDatalist7,
            'dataList8': monthDatalist8, 'month_day': month_day}
    return data


@login_required
def getRTMonitorPage(request):
    if request.method == 'GET':
        userName=request.session.get('userName')
        userr=User.objects.filter(username=userName).first()
        if userr is not None:
            data = {'status': userr.is_staff}
        else:
            data = {'status': False}  # 或者提供其他默认值或错误消息
        data.update(prepareRTMonitorPage())
        return render(request, 'gly-rt-monitor.html', data)


def getWelcomePage(request):
    return render(request, 'welcome_main.html')


@login_required
def getRecordPage(request):
    if request.method == 'GET':
        userName = request.session.get('username')
        userr = User.objects.filter(username=userName).first()
        if userr is not None:
            data = {'status': userr.is_staff}
        else:
            data = {'status': False}  # 或者提供其他默认值或错误消息
        data.update(prepareRecordPage())
        return render(request, 'record.html',data)


@login_required
def getStatisticPage(request):
    if request.method == 'GET':
        userName = request.session.get('username')
        userr = User.objects.filter(username=userName).first()
        if userr is not None:
            data = {'status': userr.is_staff}
        else:
            data = {'status': False}  # 或者提供其他默认值或错误消息
        data.update(prepareStatisticPage())
        return render(request, 'statistic.html', data )


@login_required
def getUserinfoPage(request):
    if request.method == 'GET':
        userName = request.session.get('username')
        userr = User.objects.filter(username=userName).first()
        if userr is not None:
            data = {'status': userr.is_staff}
        else:
            data = {'status': False}  # 或者提供其他默认值或错误消息
        data.update(prepareInfoManagerPage())
        return render(request, 'userInfoManager.html', data)


@login_required
def getVedioPage(request):
    if request.method == 'GET':
        userName = request.session.get('username')
        userr = User.objects.filter(username=userName).first()
        if userr is not None:
            data = {'status': userr.is_staff}
        else:
            data = {'status': False}  # 或者提供其他默认值或错误消息
        data.update(prepareVideoPage())
        return render(request, 'video.html',data)


@login_required
def getSetMonitorPage(request):
    if request.method == 'GET':
        userName = request.session.get('username')
        userr = User.objects.filter(username=userName).first()
        if userr is not None:
            data = {'status': userr.is_staff}
        else:
            data = {'status': False}  # 或者提供其他默认值或错误消息
        return render(request, 'setMonArea.html',data)


# ----------------------------------------------------process--------------------------------------------------------
# --------------------------------------------------------------------------------------------------------------------
def prepareVideoPage():
    nums = videos.objects.all().count()
    records = []
    for rec in videos.objects.all():
        records.append(rec)
    data = {'nums': nums, 'records': records}
    return data


@login_required
def processSetMonitorArea(request):
    if request.method == 'GET':
        return redirect(reverse("login"))
    else:
        # 存入数据库--------未实现
        cameraId = request.POST.get('cameraId')
        regionName = request.POST.get('regionName')

        x = request.POST.get('xRatio')
        y = request.POST.get('yRatio')
        w = request.POST.get('wRatio')
        h = request.POST.get('hRatio')

        if cameraId == '摄像头1':
            gol.set_value('xpos1', float(x))
            gol.set_value('ypos1', float(y))
            gol.set_value('width1', float(w))
            gol.set_value('height1', float(h))
        if cameraId == '摄像头2':
            gol.set_value('xpos2', float(x))
            gol.set_value('ypos2', float(y))
            gol.set_value('width2', float(w))
            gol.set_value('height2', float(h))
        if cameraId == '摄像头3':
            gol.set_value('xpos3', float(x))
            gol.set_value('ypos3', float(y))
            gol.set_value('width3', float(w))
            gol.set_value('height3', float(h))
        if cameraId == '摄像头4':
            gol.set_value('xpos4', float(x))
            gol.set_value('ypos4', float(y))
            gol.set_value('width4', float(w))
            gol.set_value('height4', float(h))

        return redirect(reverse('setMonitorPage'))


@login_required
def processGetRTData(request):
    if request.method == 'GET':
        today = datetime.datetime.today().date()
        yesterday = today + datetime.timedelta(-1)
        num = alarmRecord.objects.filter(intrusionTime__gte=today).count()
        preNum = alarmRecord.objects.filter(intrusionTime__gte=yesterday, intrusionTime__lt=today).count()
        existNumRatio = True
        numRatio = 0
        if preNum != 0:
            numRatio = (num - preNum) / preNum
        else:
            existNumRatio = False
        numMonth = alarmRecord.objects.filter(intrusionTime__gte=today.replace(day=1)).count()
        prenumMonth = alarmRecord.objects.filter(intrusionTime__gte=(today - relativedelta(months=+1)).replace(day=1),
                                                 intrusionTime__lt=today.replace(day=1)).count()
        existNumMonthRatio=True
        numMonthRatio=0
        if prenumMonth != 0:
            numMonthRatio = (numMonth - prenumMonth) / prenumMonth
        else:
            existNumMonthRatio = False
        data = {'num': num, 'numRatio': numRatio,'existNumRatio': existNumRatio,  'numMonth': numMonth,
                'existNumMonthRatio':existNumMonthRatio,'numMonthRatio':numMonthRatio}
        return JsonResponse(data)



def processAllocPermisstion(request):
    if request.method == 'GET':
        return redirect(reverse("gly-rt-monitor"))
    else:
        name = request.POST.get('name')
        allocStartTime = request.POST.get('allocStartTime')
        allocEndTime = request.POST.get('allocEndTime')
        rgn = request.POST.get('rgn')
        reg = rgn.split('/')
        regin = region.objects.filter(regionName=reg[1], cameraId=reg[0]).first()
        truStaff = trustedStaff.objects.filter(name=name).first()
        person = trustedStaffPermission.objects.filter(name=truStaff, regionId=regin, start_time=allocStartTime,
                                                       end_time=allocEndTime).first()
        if person:
            return render(request, 'userInfoManager.html', prepareInfoManagerPage())

        person = trustedStaffPermission(name=truStaff, regionId=regin, start_time=allocStartTime, end_time=allocEndTime)
        person.save()
        return redirect(reverse('infoManager'))


# 记得处理表单问题或者交给前端
@login_required
def processTrustForm(request):
    if request.method == 'GET':
        return redirect('reverse("gly-rt-monitor")')
    else:
        name = request.POST.get('name')
        age = request.POST.get('age')
        sex = request.POST.get('selection')  # man or woman
        email = request.POST.get('email')
        img = request.FILES.get('upload_image')

        if sex == 'man':
            sex = '男'
        if sex == 'woman':
            sex = '女'
        person = trustedStaff(name=name, age=age, sex=sex, email=email, image=img)
        person.save()

        path = MEDIA_ROOT + '/' + str(person.image)
        print(path)
        img = cv2.imread(path)
        getFace(img, name)
        reFlushFaceDB()
        return redirect(reverse("gly-rt-monitor"))


@login_required
def processDeleteRecord_user(request):
    if request.method == 'GET':
        return redirect('reverse("login")')
    else:
        id = request.POST.get('id')
        userr = User.objects.filter(username=id).first()
        userr.delete()
        return redirect(reverse("infoManager"))


@login_required
def processdeleteRecord(request):
    if request.method == 'GET':
        return redirect('reverse("login")')
    else:
        id = request.POST.get('time')
        dateTime_p = datetime.datetime.strptime(id, '%Y-%m-%d %H:%M:%S')
        alarmRec = alarmRecord.objects.filter(intrusionTime=dateTime_p).first()
        alarmRec.delete()
        return redirect(reverse("record"))


@login_required
def processDeleteRecord_trust(request):
    if request.method == 'GET':
        return redirect('reverse("login")')
    else:
        id = request.POST.get('id')
        truStaff = trustedStaff.objects.filter(name=id).first()

        path1 = 'C:/Users/86136/Desktop/faces/' + truStaff.name
        if os.path.exists(path1):
            shutil.rmtree(path1)
            reFlushFaceDB()

        truStaff.delete()
        return redirect(reverse("infoManager"))


@login_required
def processDeleteRecord_truPermission(request):
    if request.method == 'GET':
        return redirect(reverse("login"))
    else:
        name = request.POST.get('name')
        cameraName = request.POST.get('cameraName')
        reginName = request.POST.get('reginName')  # man or woman
        startTime = request.POST.get('startTime')
        endTime = request.POST.get('endTime')

        truStaff = trustedStaff.objects.filter(name=name).first()
        rgn = region.objects.filter(regionName=reginName, cameraId=cameraName).first()
        truPer = trustedStaffPermission.objects.filter(name=truStaff, regionId=rgn, start_time=startTime,
                                                       end_time=endTime).first()
        truPer.delete()
        return redirect(reverse("infoManager"))

@login_required
def processAllocUser(request):
    if request.method == 'GET':
        return redirect(reverse("login"))
    else:
        name=request.POST.get('name')
        userr = User.objects.filter(username=name).first()
        userr.is_staff=1
        userr.save()
        return redirect(reverse("infoManager"))


@login_required
def processSelectIdenObj(request):
    if request.method == 'GET':
        name = request.GET.get('selValue')
        gol.set_value('otherObject', name)

    return JsonResponse('success', safe=False)


def tech(request):
    return render(request, 'tech.html')

def aboutus(request):
    return render(request, 'aboutus.html')

